﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Timers;
using Mighty.Common;
using Mighty.Brain;
using System.Windows.Forms;

namespace Mighty.PlayingBoard
{
    public class AIConnector : Connector
    {
        public PlayingBoard playingBoard { get; set; }

        private Object brainInstance;
        private FieldInfo gameInfo;
        private MethodInfo gameStartEvent;
        private MethodInfo bettingReadyEvent;
        private MethodInfo bettingTicEvent;
        private MethodInfo bettingCompleteEvent;
        private MethodInfo choiceCardEvent;
        private MethodInfo choiceFriendEvent;
        private MethodInfo lastBettingEvent;
        private MethodInfo roundReadyEvent;
        private MethodInfo roundTicEvent;
        private MethodInfo roundCompleteEvent;
        private MethodInfo gameEndEvent;

        public AIConnector(Type type, int p)
            : base(p)
        {
            position = p;
            brainInstance = Activator.CreateInstance(type);

            gameInfo = type.GetField("gameInfo");
            gameStartEvent = type.GetMethod("GameStartEvent");
            bettingReadyEvent = type.GetMethod("BettingReadyEvent");
            bettingTicEvent = type.GetMethod("BettingTicEvent");
            bettingCompleteEvent = type.GetMethod("BettingCompleteEvent");
            choiceCardEvent = type.GetMethod("ChoiceCardEvent");
            choiceFriendEvent = type.GetMethod("ChoiceFriendEvent");
            lastBettingEvent = type.GetMethod("LastBettingEvent");
            roundReadyEvent = type.GetMethod("RoundReadyEvent");
            roundTicEvent = type.GetMethod("RoundTicEvent");
            roundCompleteEvent = type.GetMethod("RoundCompleteEvent");
            gameEndEvent = type.GetMethod("GameEndEvent");
        }

        override public void SetGameInfo(GameInfo g)
        {
            gameInfo.SetValue(brainInstance, g);
            if (playingBoard.gameMode == GameMode.Offline && position == 0 ) playingBoard.iVisual.SetGameInfo(g);
            
            //if (position == 0)
              //  playingBoard.SetMyGameInfo(g);
        }

        public void SetPlayingBoard(PlayingBoard p)
        {
            playingBoard = p;
        }

        override protected Object RequestInvoke()
        {
            Object result = null;

            //if (playingBoard.isPlayer && position == 0) playingBoard.SetFlag(threadActualStatus);
            if (playingBoard.gameMode == GameMode.Offline && position == 0) playingBoard.iVisual.Visualize(threadActualStatus, position);

            try
            {
                switch (threadActualStatus)
                {
                    case ActualStatus.GameStartEvent:
                        result = gameStartEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.BettingReadyEvent:
                        result = bettingReadyEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.BettingTicEvent:
                        Betting betting = (Betting)bettingTicEvent.Invoke(brainInstance, null);
                        betting.position = position;
                        result = betting;
                        break;
                    case ActualStatus.BettingCompleteEvent:
                        result = bettingCompleteEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.ChoiceCardEvent:
                        //if (position == 0)
                        //    playingBoard.SetPlayerState(PlayerState.choiceCard);
                        result = choiceCardEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.ChoiceFriendEvent:
                        result = choiceFriendEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.LastBettingEvent:
                        result = lastBettingEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.RoundReadyEvent:
                        //if (playingBoard.isPlayer && position == 0) playingBoard.SetPlayerState(PlayerState.endBetting);
                        result = roundReadyEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.RoundTicEvent:
                        //if (playingBoard.isPlayer && position == 0)
                        //{
                        //    playingBoard.SetPlayerState(PlayerState.selRoundCard);
                        //    playingBoard.autoEvent = new AutoResetEvent(false);
                        //    playingBoard.autoEvent.WaitOne(1000, false);
                        //    playingBoard.SetPlayerState(PlayerState.endRoundCard);
                        //}
                        result = roundTicEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.RoundCompleteEvent:
                        //if (playingBoard.isPlayer && position == 0)
                        //{
                        //    playingBoard.SetPlayerState(PlayerState.endThrowing);
                        //}
                        result = roundCompleteEvent.Invoke(brainInstance, null);
                        break;
                    case ActualStatus.GameEndEvent:
                        result = gameEndEvent.Invoke(brainInstance, null);
                        break;
                }
            }
            catch (Exception)
            {
            }
            return result;
        }

    }
}
